using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;

namespace MiniStock.Entities.Common.Events
{
    [DataContract]
    [KnownType("GetKnownTypes")]
    public abstract class EntityEventBase: EventBase
    {
        public abstract bool IsConstructionMessage { get; }

        public abstract string GetEntityHash();

        public virtual void ApplyTo(EntityBase entity)
        {
            throw new NotImplementedException();
        }

        public virtual void ValidateFor(EntityBase entity, IEntityProvider provider)
        {
            if(IsConstructionMessage && entity != null)
                throw new ValidationException("Construction message cannot be called for duplicates");

            if(!IsConstructionMessage && entity == null)
                throw new ValidationException("Entity not found");
        }

        public abstract Type GetEntityType();

        public static IEnumerable<Type> GetKnownTypes()
        {
            List<Type> result = new List<Type>();
            result.AddRange(SerializationHelper.KnownEventTypes);
            result.Add(typeof(ResultEvent));
            result.Add(typeof(MessageProcessedEvent));
            result.Add(typeof(MessagePersistedEvent));
            result.Add(typeof(MessageFaultedEvent));
            return result;
        }
    }
}
